<template>
  <div class="table-warp" :style="styleHeight">
    <input type="file" id="fileXlsx" style="display:none;"/>
    <el-card class="table-top">
      <el-form :inline="true" :model="pageQuery" class="demo-form-inline" size="small">
        <el-form-item :label="title">
          <el-input v-model="pageQuery.search" :placeholder="`模糊输入${title}`"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" @click="search" :loading="exportLoading">搜索</el-button>
          <el-button type="info" icon="el-icon-refresh" @click="initPage" :loading="exportLoading">重置</el-button>
          <el-button type="primary" icon="el-icon-plus" v-if="isAllowAdd" @click="onTopAddDataClick">添加
          </el-button>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-download" @click="exportDialog.dialogVisible = true "
                     :loading="exportLoading">导出
          </el-button>
          <el-button type="success" icon="el-icon-upload2" disabled @click="onImport" :loading="exportLoading">导入
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!--  文件导出组件  -->
    <file-export v-if="exportDialog.dialogVisible"
                 @closeExportDialog="exportDialog.dialogVisible = false"
                 :datas="tableData"
                 :title="title"
                 :headers="headers"
    ></file-export>

    <!--  列表  -->
    <el-card class="table-center" ref="tablesCardRef">
      <el-table :data="tableData" stripe v-loading="pageQuery.loading" element-loading-text="拼命加载中" ref="tablesRef"
                id="tablesRef" style="width: 100%" :max-height="tableHeight">
        <el-table-column type="selection" width="55" align="center"
        ></el-table-column>

        <el-table-column v-for="(header,key) in headers" :key="key" :prop="header.key" :label="header.label"
                         :formatter="columnFormatter"
        ></el-table-column>


        <el-table-column label="操作" min-width="100" fixed="right" header-align="center">
          <template slot-scope="scope">
            <el-button @click="onTableHandleGetClick(scope.row)" type="success" size="small">查看</el-button>
            <el-button v-if="isAllowUpdate(scope.row)" size="small" @click="onTableHandleUpdateClick(scope.row)" type="primary"
                       >编辑
            </el-button>
            <el-button v-if="isAllowDelete(scope.row)" size="small" @click="onTableHandleDeleteClick(scope.row)" type="danger"
                       >删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <el-card class="table-bottom">
      <el-pagination style="text-align: right;" background @size-change="handleSizeChange"
                     @current-change="handleCurrentChange" :page-sizes="[10, 20, 30,50,100]"
                     :current-page="pageQuery.page"
                     :page-size="pageQuery.size" layout="total, sizes, prev, pager, next, jumper"
                     :total="pageQuery.total">
      </el-pagination>
    </el-card>


    <el-dialog
        :visible.sync="editDialogVisible"
        width="80%"
    >
      <!--  详情 ，使用插槽，可以在父组件中自行替换掉此部分 -->
      <slot name="detail-slot">
        <!--如果有展示权限，则将弹出页拆分两列，左侧展示基本数据，右侧展示权限数据-->
        <div :class="editDialogType==='detail'?'box-card-disable':'box-card-enable'">
          <template v-if="hasAuthObject">
            <el-row>
              <!--左侧显示表单-->
              <el-col :span="10">
                <form-detail :data="currentData" :headers="headers"></form-detail>
              </el-col>
              <el-col :span="1">
                <el-divider direction="vertical"/>
              </el-col>
              <!--右侧显示权限-->
              <el-col :span="13">
                <auth-object
                    :auth-object="currentData.authObject"
                    :title="authTitle"
                ></auth-object>
              </el-col>
            </el-row>
          </template>
          <template v-else>
            <form-detail :data="currentData" :headers="headers"></form-detail>
          </template>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button @click="editDialogVisible = false">返回</el-button>
          <el-button v-if="editDialogType==='add' && isAllowAdd()" type="primary" @click="onDialogHandleAddCLick()"
          >新增</el-button>
          <el-button v-if="editDialogType==='update' && isAllowUpdate(currentData)" type="primary"
                     @click="onDialogHandleUpdateCLick()"
          >修改</el-button>
          <el-button v-if="editDialogType==='update' && isAllowDelete(currentData)" type="danger"
                     @click="onDialogHandleDeleteClick"
          >删除</el-button>
        </span>
      </slot>
    </el-dialog>

  </div>
</template>

<script>
import FileExport from "@/components/fileExport"
import {importXlsx} from '@/utils/importExport'
import FormDetail from "@/components/search-table/FormDetail.vue";
import AuthObject from "@/components/auth-object/index.vue";

export default {
  /*
      title="用户"   //组件页面展示的主题信息，详情页也使用这个
      authTitle="表单编辑"   //权限数据，有此字段表示展示详情也会展示 currentData.authObject权限字段
      :headers="headers"   //表单头部字段信息，同时也是详情页的字段信息
      :searchData="searchUser"  // 分页查询接口，用于查询分页的返回数据，以供渲染
      :doUpdate="updateUser"  //默认slot插槽，执行具体的更新逻辑
      :doDelete="deleteUser"  //默认slot插槽，执行具体的删除逻辑
   */
  name: 'SearchTable',
  components: {AuthObject, FormDetail, FileExport},
  props: {
    title: {
      type: String,
      default() {
        return "主题"
      }
    },
    authTitle: {
      type: String,
      required: false
    },
    headers: {
      type: Array,
      required: true
      /*  默认type : input ,input中的值类型subType，可以为 string或number
          只有 radio select checkbox 有options选项参数options，为其子属性
          如果不需要展示详情页面，使用自定义的详情页面，则不需要type和option，但注意需要把columnFormatter回调函数传处理好
      *示例  headers:[
        {key:'id',label:'ID'     ,forbiddenEdit:true                                                                                },
        {key:'name',label:'姓名'                                                                                                     },
        {key:'nickName',label:'昵称'                                                                                                 },
        {key:'phone',label:'电话'                                                                                                    },
        {key:'age',label:'年龄',subType:'number'                                                                                     },
        {key:'email',label:'邮件',        type:"input"                                                                               },
        {key:'gender',label:'性别',       type:"radio"           ,options:[{key:1,label:'男'},{key:2,label:'女'},{key:3,label:'其他'}]},
        {key:'gender',label:'性别button', type:"radio-button"    ,options:[{key:1,label:'男'},{key:2,label:'女'},{key:3,label:'其他'}]},
        {key:'gender',label:'性别select', type:"select"          ,options:[{key:1,label:'男'},{key:2,label:'女'},{key:3,label:'其他'}]},
        {key:'gender',label:'checkbox',  type:"checkbox"        ,options:[{key:1,label:'男'},{key:2,label:'女'},{key:3,label:'其他'}]},
        {key:'gender',label:'checkbox',  type:"checkbox-button" ,options:[{key:1,label:'男'},{key:2,label:'女'},{key:3,label:'其他'}]},
        {key:'createTime',label:'创建日期',type:"datetime"  ,forbiddenEdit:true                                                      },
      ]
      * */
    },
    searchData: {
      type: Function,  //Promise
      required: true
    },
    //是否允许新增
    isAllowAdd: {
      type: Function,
      default() {
        return this.doAdd != null;
      }
    },
    doAdd: {
      type: Function,
      required: false,
      default(data) {
        return Promise.resolve(data);
      }
    },
    //是否允许更新
    isAllowUpdate: {
      type: Function,
      default(data) {
        let b = this.doUpdate != null;
        //console.log("isAllowUpdate",b)
        return b;
      }
    },
    //执行页面更新
    doUpdate: {
      type: Function,
      required: false
    },
    //是否允许删除
    isAllowDelete: {
      type: Function,
      default(data) {
        let b = this.doDelete != null;
        //console.log("isAllowDelete",b)
        return b;
      }
    },
    //执行删除
    doDelete: {
      type: Function,
      required: false,
    }
  },
  data() {
    return {
      exportLoading: false,
      exportDialog: {
        dialogVisible: false,
        fileName: '数据',
        fileType: 'xlsx'
      },
      tableHeight: 0,
      pageQuery: {
        search: null,
        page: 1,
        size: 10,
        total: 0,
        loading: false,
      },
      tableData: [],
      // 弹出框相关
      editDialogVisible: false,
      editDialogType: 'detail',
      currentData: {}
    }
  },
  computed: {
    hasAuthObject() {
      return this.authTitle != null
    },
    //表单的格式化方法，用于枚举等展示和字段值不一致的情况
    columnFormatter() {
      //默认就直接返回数据了，这每个元素解析都会调用
      return (row, column, value, index) => {
        let property = column.property;
        for (let header of this.headers) {
          if (header.key == property) {
            if (header.options) {
              for (let option of header.options) {
                //val 可以是 gender的值1 2 ......
                //let value = row[property]
                if (value == option.key) {
                  return option.label
                }
              }
            }
          }
        }
        //return row[property];
        return value;
      }
    },
    // 动态高度，适配各布局。单页面的话，高度设为100%即可。
    styleHeight() {
      let {layout, isTagsView} = this.$store.state.layoutConfig;
      if (layout === 'fashion' || layout === 'strange') {
        if (isTagsView) {
          return {
            height: `calc(100vh - 84px)`
          }
        } else {
          return {
            height: `calc(100vh - 50px)`
          }
        }
      } else {
        return {
          height: `calc(100vh - 50px)`
        }
      }
    },

  },
  mounted() {
    this.setTableHeight();
    this.search()
  },
  methods: {
    initPage() {
      this.pageQuery = {
        name: null,
        page: 1,
        size: 10,
        total: 0,
        loading: false
      }
      this.currentData = {}
      this.editDialogVisible = false;
      this.editDialogType = '';
      this.search()
    },
    //搜索
    search() {
      this.searchData({
        page: this.pageQuery.page,
        size: this.pageQuery.size,
        search: this.pageQuery.search,
      }).then((res) => {
        let data = res.data;
        this.pageQuery.total = data.total
        this.tableData = data.data
      })
    },
    onTopAddDataClick() {
      this.currentData = {
        authObject:{}
      }
      this.editDialogType = 'add'
      this.editDialogVisible = true
    },
    // 查看点击
    onTableHandleGetClick(data) {
      this.editDialogType = 'detail'
      this.currentData = data
      this.editDialogVisible = true
    },
    // table 修改点击
    onTableHandleUpdateClick(data) {
      this.editDialogType = 'update'
      this.currentData = data
      this.editDialogVisible = true
    },
    // table 删除点击
    onTableHandleDeleteClick(data) {
      this.$confirm('确定要删除吗，删除后无法找回？', '确认信息', {
        distinguishCancelAndClose: true,
        confirmButtonText: '确认删除',
        cancelButtonText: '取消'
      })
          .then(() => {
            this.doDelete(data).then(res => {
              this.$message({
                type: 'success',
                message: '删除成功'
              });
              this.initPage()
            })
          })
          .catch(action => {
            this.$message({
              type: 'info',
              message: action === 'cancel'
                  ? '放弃保存并离开页面'
                  : '停留在当前页面'
            })
          });

    },
    //弹出框点击更新
    onDialogHandleAddCLick() {
      console.log("currentData",this.currentData)
      this.doAdd(this.currentData).then(() => {
        this.$message({
          type: 'success',
          message: '新增成功'
        });
        this.editDialogVisible = false
        this.initPage()
      })
    },
    //弹出框点击更新
    onDialogHandleUpdateCLick() {
      this.doUpdate(this.currentData).then(() => {
        this.$message({
          type: 'success',
          message: '修改成功'
        });
        this.initPage()
      })
    },
    // 弹出框点击删除
    onDialogHandleDeleteClick(data) {
      this.onTableHandleDeleteClick(data)
    },
    // 分页点击
    handleSizeChange(val) {
      this.pageQuery.size = val;
      this.pageQuery.page = 1;
      this.search()
    },
    // 分页点击
    handleCurrentChange(val) {
      this.pageQuery.page = val;
      this.search()
    },
    // 导入点击
    onImport() {
      // 标题头格式
      let header = [{date: '日期'}, {name: '姓名'}, {address: '地址'}, {goodsName: '商品名称'}, {desc: '描述'}];
      // 获取 input，触发上传
      let el = document.getElementById('fileXlsx');
      el.outerHTML = el.outerHTML; // 每次上传前清空之前的数据
      el.click();
      importXlsx(el, header, res => {
        this.tableData = res;
        this.pageQuery.total = res.length;
      });
    },
    // 表格高度
    setTableHeight() {
      this.$nextTick(() => {
        this.tableHeight = `${this.$refs.tablesCardRef.$el.clientHeight}px`;
      })
    },
  }
}
</script>

<style scoped lang="scss">
.table-warp {
  display: flex;
  flex-direction: column;

  .table-top {
    padding: 10px;

    ::v-deep .el-form-item--small.el-form-item {
      margin-bottom: 0 !important;
    }
  }

  .table-center {
    flex: 1;
    display: flex;
    border-top: transparent;
    border-bottom: transparent;

    ::v-deep .el-card__body {
      display: flex;
      flex-direction: column;
      flex: 1;
      width: 100%;
    }
  }

  .table-bottom {
    padding: 10px;
  }
}
.box-card-disable {
  pointer-events: none;
}
.box-card-enable {
  //pointer-events: none;
}

.el-divider--vertical {
  display: inline-block;
  width: 1px;
  height: 55em;
  margin: 8px;
  left: 10px;
  vertical-align: middle;
  position: relative;
}
</style>
